[% setvar title Distinguish packed data from printable strings %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Distinguish packed data from printable strings</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: Tim Conrow &lt;<a href='mailto:tim@ipac.caltech.edu'>tim@ipac.caltech.edu</a>&gt;
  Date: 18 Sept 2000
  Last Modified: 28 Sep 2000
  Mailing List: <a href='mailto:perl6-language@perl.org'>perl6-language@perl.org</a>
  Number: 258
  Version: 2
  Status: Frozen</pre>
<a name='NOTES ON THE FREEZE'></a><h1>NOTES ON THE FREEZE</h1>
<p>As expected, there was very little interest in this RFC, so with a few
minor tweaks intended to reduce misunderstanding, I'm going to freeze
it and let it recede into the background of lesser RFCs.</p>
<a name='CHANGES'></a><h1>CHANGES</h1>
<p>Added some text for clarity. A few rewordings. One or two minor tweaks
to my current idea of DWIMish behavior for packed data.</p>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>Perl6 should be able to DWIMishly distinguish between strings which
are likely to be meant to be human readable (called printable strings
here-after) and packed data structures stored as strings. This would
permit greater specificity in programming and thus better error
checking.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>Although there is no way for perl6 to be sure whether a user intends a
particular string to be human readable or not, it could DWIMishly get
it right a large fraction of the time, analogous to how perl now
differentiates between a string and a numeric. Doing so would permit
some useful error checking and help users, especially new users, avoid
some common mistakes made in perl5, such as the confusion between the
two meanings of <code>&amp;</code>. If the DWIMery is tuned correctly there would be
very little interference with common (and correct) coding idioms.</p>
<p>A new scalar flag, which I'll call PkOK (for &quot;Packed OK&quot;), would be
set in a scalar's flags by any builtin function or operator that
produces a string which is likely to be a packed data structure of
some sort rather than a printable string or a numeric value. These
include <code>pack</code>, <code>read</code>, <code>sysread</code>, <code>vec</code>, the multi-argument form
of <code>select</code>, the string-context form of operators <code>&gt;&gt;, &lt;&lt;, |, &amp;,
^, ~</code>, the addresses returned by the <code>gethost*</code> routines, and,
well, you get the idea.</p>
<p>The generation of warnings or errors would only occur if the user
invoked <code>use warnings 'packed'</code> and/or <code>use strict 'packed'</code>
explicitly. Without these pragmas, Perl6's behavior regarding packed
data would be like Perl5's.</p>
<p>With packed strings recognizable to the compiler and interpreter
through the PkOK bit, they would interact with functions, operators,
and other relevant scalar types as follows. How DWIMish some of these
are is debatable.</p>
<pre>  use warnings 'packed';
  use strict   'packed';

  # The notation &quot;$a(PkOK) = X&quot; means $a has its PkOK bit set to X and
  # is thus regarded as packed data.

  $a = pack(&quot;A*&quot;,&quot;abc&quot;);   # $a(PkOK) = 0; printable string
  $a = pack(&quot;U*&quot;,&quot;abc&quot;);   # $a(PkOK) = 0; printable string
  $a = pack(&quot;a*&quot;,&quot;123&quot;);   # $a(PkOK) = 1; packed thing
  print $a;                # Implicitly stringify $a, no warning
  print &quot;$a&quot;;              # Explicitly stringify $a; no warning
  $b = pack($tmpl8,@data); # $b(PkOK) = 1; packed things
  $c = $a ^ $b;            # String context xor. $c(PkOK) = 1
  $d = &quot;255&quot;;
  $e = &quot;13&quot;;
  $c = $d ^ $e;            # Numeric context xor via promotion to numeric.
  $d = $a ^ 255;           # Error; mixing modes of ^.
  $d = $a ^ &quot;zzz&quot;;         # Promote via pack(&quot;a*&quot;,&quot;zzz&quot;), but issue warning
  $e = vec($a,12,4);       # OK; $e is numeric; $e(PkOK) = 0
  $e = vec(1234,1,8);      # Error; won't auto-promote numerics
  vec(1234,1,8) = 1;       # Error
  $short = &quot;\x04\x12&quot;;     $ $e(PkOK) = 0, even though it's &quot;binary&quot;
  $e = vec($short,1,8);    # Promote $short, issue warning
  vec($short,1,8) = 1;     # Promote $short, no warning
  select(undef,$rin=0,undef,0.25);  # Error
  select(undef,$rin=&quot;&quot;,undef,0.25); # Promote $rin, no warning
  $a = pack(&quot;a*&quot;,&quot;123&quot;);
  $b = pack(&quot;a*&quot;,&quot;456&quot;);
  $c = $a + $b;            # Error
  $c = &quot;$a&quot; + &quot;$b&quot;;        # Weird, but OK
  $c = &lt;STDIN&gt;;            # $c(PkOK) = 0; $c is a normal string
  sysread FOO,$a,16;       # $a(PkOK) = 1; $a is a packed thing
  syswrite BAR,123;        # Error
  syswrite BAR,&quot;123&quot;;      # Promote, issue warning
  syswrite BAR,pack &quot;a*&quot;,&quot;123&quot;;     # OK
  if($a) ...               # Always true
  if($a eq &quot;xxx&quot;) ...      # Stringify, issue warning
  if(&quot;$a&quot; eq &quot;xxx&quot;) ...    # Stringify, no warning
  if($a == 123) ...        # Error</pre>
<p>The exceptions for <code>print $a</code> (where $a is stringified with a
warning), vec and select (where string arg.s auto-promoted with
<code>pack(&quot;a*&quot;,$str)</code> without warnings) are for backward compatibility
with commonly employed idioms.</p>
<p>I'm sure I haven't covered all the relevant cases, but I hope the
intent is clear: to cut down on the room for accidental use of packed
data in inappropriate circumstances and to increase the ability of the
user to be specific regarding intent. In particular, accidentally
using string context bit ops when meaning to use numeric, or vice
versa, would raise a warning, and mixing numeric and packed arg.s
would be an error.</p>
<p>If anyone knows of common constructs/idioms which would break under
this scheme and where it's too painful to add explicit
<code>pack(&quot;a*&quot;,...)</code> or <code>&quot;...&quot;</code> as appropriate ... well I don't have to
ask to have them pointed out, do I? :-) The only cases I've been able
to think of are JAPHs or code samples.</p>
<p>If RFCs 73 and/or 161 end up being adopted, the idea of packed things
being distinct could be extended to allow additional functionality. E.g.</p>
<pre>  $a = pack(&quot;l*&quot;,12,34); # Save the template in the instance data
  if(ref($a) eq &quot;Packed&quot;) { ... }
  @b = $a-&gt;unpack;            # Use saved template
  $a-&gt;STRING = sub { join &quot;,&quot;,$_[0]-&gt;unpack; };
  print &quot;$a\n&quot;; # Readable through use of STRING</pre>
<p>If RFC 89 is adopted, a variable could be forced to hold only packed
things. E.g.</p>
<pre>  my packed $thingie : (template=&gt;&quot;lll&quot;);
  $thingie-&gt;pack 123,456,789;</pre>
<p>... or something like that.</p>
<p>How this would interact with RFCs 142,246-250 is TBD, but I see no
outright conflicts right off. This might dovetail well with RFC 159 to
allow un/packing on the fly based on context, but I'm not sure.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>I know almost nothing about internals, so this is probably wrong, but
see if I convey my meaning anyway.</p>
<li><a name='With certain exceptions for vec and select, exemplified above, builtin operators and functions which expect to operate on packed data structures (including bitwise ops) would behave thusly if use warnings 'packed' and use strict 'packed' are in effect:'></a>With certain exceptions for <code>vec</code> and <code>select</code>, exemplified above,
builtin operators and functions which expect to operate on packed data
structures (including bitwise ops) would behave thusly if <code>use
warnings 'packed'</code> and <code>use strict 'packed'</code> are in effect:</li>
<pre>  NOK  POK PkOK
  -------------
   0    0    1   not possible?
   0    1    0   promote via C&lt;pack(&quot;a*&quot;,...)&gt;, issue warning
   0    1    1   OK
   1    0    0   error
   1    0    1   not possible?
   1    1    0   promote, issue warning
   1    1    1   OK</pre>
<li><a name='With certain exceptions for print and &quot;&quot;, exemplified above, builtins expecting a &quot;printable string&quot; would issue a warning if given a scalar with the PkOK bit set.'></a>With certain exceptions for <code>print</code> and <code>&quot;&quot;</code>, exemplified above,
builtins expecting a &quot;printable string&quot; would issue a warning if given
a scalar with the PkOK bit set.</li>
<li><a name='By way of an imperfect analogy, note the similarity between packed strings having a PkOK flag via pack (and others) and regexs having an ROK flag via qr().'></a>By way of an imperfect analogy, note the similarity between packed
strings having a PkOK flag via <code>pack</code> (and others) and regexs having
an ROK flag via <code>qr()</code>.</li>
<a name='MIGRATION'></a><h1>MIGRATION</h1>
<p>When translating code with p526, put</p>
<pre>  no warnings 'packed';
  no strict   'packed';</pre>
<p>at the start of each lexical structure.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>RFC 73: All Perl core functions should return objects</p>
<p>RFC 89: Controllable Data Typing</p>
<p>RFC 142: Enhanced Pack/Unpack</p>
<p>RFC 159: True Polymorphic Objects</p>
<p>RFC 161: Everything in Perl becomes an object.</p>
<p>RFC 246: pack/unpack uncontrovercial enhancements</p>
<p>RFC 247: pack/unpack C-like enhancements</p>
<p>RFC 248: enhanced groups in pack/unpack</p>
<p>RFC 249: Use pack/unpack for marshalling</p>
<p>RFC 250: hooks in pack/unpack</p>
</div>
